#include "sk_form_tf.h"
#include "ui_sk_form_tf.h"
#include "pub_var.h"

#include <QSettings>
#include <QMessageBox>
#include <QDebug>
#include <QSqlError>
#include <QSqlRecord>
#include <QDateTime>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>

#include <QNetworkReply>

Form_tf::Form_tf(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form_tf)
{

    ui->setupUi(this);
    //窗口标题
    this->setWindowTitle("退费管理－当前用户－"+pub::usr_name);

    QSettings setIni("clin.ini", QSettings::IniFormat);
    //恢复当前窗口位置
    QRect rct = setIni.value("windowState/tf").toRect();
    this->setGeometry(rct);

    //数据库连接
    qrm = new QSqlQuery(pub::db_m);
    qro = new QSqlQuery(pub::db_o);
    qro2 = new QSqlQuery(pub::db_o);

    //预置退费类别
    ui->rbG->setChecked(true);

    //预置执行按钮无效
    ui->pbExecute->setEnabled(false);
    ui->pb_reprint->setEnabled(false);

    //列表字体
    ui->tvItemList->setFont(this->font());

    //退费权限查询
    sq = "select role_dept from com_privileges where code = '"
            + pub::usr_code + "' and role_dept = '财务'";
    qDebug()<<"检索系统当前用户权限 : "<<sq;
    qrm->exec(sq);

    if(qrm->size() < 1)
    {
        //ui->rbG->setEnabled(false);
        privFinance = false;
    }
    else
    {
        //ui->rbG->setEnabled(true);
        privFinance = true;
    }

    qDebug()<<"privFinance is "<<privFinance;

    ui->rbS->setChecked(true);

    //网络参数
    request.setUrl(QUrl(pub::hos_ybjy));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

    bill_print = new sk_print_bill();

}

Form_tf::~Form_tf()
{
    delete ui;
    delete bill_print;
}

void Form_tf::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
    QSettings setIni("clin.ini", QSettings::IniFormat);
    setIni.setValue("windowState/tf", QVariant(this->geometry()));
    destroyW("form_tf");

}

void Form_tf::resizeEvent(QResizeEvent *event)
{

    Q_UNUSED(event);
    //窗口界面大小变化，重新设定
}

void Form_tf::prepare_recipe()
{
    QString invo_no = pub::add0(ui->leFph->text(),12);
    mpPerson.clear();
    mpPerson["invoice_no"] = invo_no;      //

    sq = "select item_name, specs, price_unit, qty/pack_qty , unit_price," //0-4
         " (qty/pack_qty) * unit_price , recipe_no, "//5-6
         " clinic_code, cancel_flag,drug_flag "//7-9
         " from fin_opb_feedetail "
         " where invoice_no ='" + invo_no + "'";

    qDebug()<<"提取收费发票号关联的处方"<<sq<<"\n";

    //提取发票号关联的处方号
    recipes.clear();
    qro->exec(sq);

    //退费允许状态标志
    bool execute_enable = true;

    while(qro->next())
    {
        recipes << qro->value(6).toString();

        mpPerson["clinic_code"] = qro->value("clinic_code").toString();   //

        if(qro->value("cancel_flag").toString() == "0")
        {
            QMessageBox::information(this,"注意","此号已经有过作废操作！");
            return;
        }

        if(privFinance)
        {
            //财务权限用户，允许重新打印未作废的发票
            ui->pb_reprint->setEnabled(true);
        }

        if(qro->value("drug_flag").toString() == "1")
        {
            //药品项目
            //检查是否已经发药
            qro2->exec("select recipe_state from pha_sto_recipe "
                       " where invoice_no = '" + invo_no + "'");
            qro2->next();

            if(qro2->value(0).toString() == "3")
            {
                //已经发药，检查药局是否完成退药过程
                qro2->exec("select * from MET_NUI_CANCELITEM "
                           " where bill_no = '" + invo_no + "'");
                //暂时只检查数据有无，不核查项目是否完全一致。
                if(!qro2->next())
                {
                    //药局过程未完成，设置退费允许状态禁止
                    ui->lb_status->setText("药局退药未完成，不可以进行退费操作");
                    execute_enable = false;
                }
            }
        }
    }

    if(recipes.isEmpty())
    {
        QMessageBox::information(this,"注意","找不到指定的发票号，退票类别选择是否正确？");
        return;
    }

    mdList.setQuery(sq, pub::db_o);

    mdList.setHeaderData(0, Qt::Horizontal, "品名");
    mdList.setHeaderData(1, Qt::Horizontal, "规格");
    mdList.setHeaderData(2, Qt::Horizontal, "单位");
    mdList.setHeaderData(3, Qt::Horizontal, "数量");
    mdList.setHeaderData(4, Qt::Horizontal, "价格");
    mdList.setHeaderData(5, Qt::Horizontal, "金额");
    double width = ui->tvItemList->width() - 50;
    ui->tvItemList->setModel(&mdList);

    pub::setColumnWidth(ui->tvItemList, "0.3^0.2^0.1^0.1^0.125^0.125^0^0^0^0^0^0^0", width, 15);

    qro->prepare("select pact_code, clinic_code from fin_opb_invoiceinfo "
                 " where invoice_no = '" + invo_no + "' and trans_type = '1' ");
    qro->exec();
    qro->next();

    mpPerson["pact_code"] = qro->value(0).toString();
    mpPerson["clinic_code"] = qro->value(1).toString();

    if(mpPerson["pact_code"] == "2")
    {
        //医保患者

        if(!pub::useInsurance)
        {
            //QMessageBox::information(this,"错误","没有进行医保登录，无法对医保发票退费！");
            ui->lb_status->setText("没有进行医保登录，无法对医保发票退费");
            execute_enable = false;
        }

        sq = "select setl_id, mdtrt_id, psn_no, insuplc_admdvs from fin_ipr_siinmaininfo "
             " where inpatient_no = '" + mpPerson["clinic_code"] + "' "
             " and invoice_no = '" + pub::add0(ui->leFph->text(),12) +"'";
        qDebug()<<"提取退费需要的医保信息："<<sq<<"\n";
        qro->exec(sq);
        if(qro->next())
        {
            mpPerson["setl_id"] = qro->value(0).toString();
            mpPerson["mdtrt_id"] = qro->value(1).toString();
            mpPerson["psn_no"] = qro->value(2).toString();
            mpPerson["insuplc_admdvs"] = qro->value(3).toString();
        }
        else
        {
            //QMessageBox::information(this,"错误","医保患者 fin_ipr_siinmaininfo 检索失败，无法进行作废操作！");
            ui->lb_status->setText("医保患者 fin_ipr_siinmaininfo 检索失败，无法进行作废操作");
            execute_enable = false;
        }
    }

    if(execute_enable)
    {
        //ui->lb_status->setText("检索成功，可以进行作废操作");
        ui->lb_status->setText("");
        ui->pbExecute->setEnabled(true);
    }
    else
    {
        ui->pbExecute->setEnabled(false);
    }
}

void Form_tf::prepare_reg()
{
    ui->pb_reprint->setEnabled(false);

    sq = "select card_no,name, dept_name, to_char(reg_date,'yyyy-mm-dd hh24:mi:ss'),"//0-3
         "pact_name, oper_code, pact_code, invoice_no, valid_flag, "//4-8
         "ynsee, clinic_code, rowid, idenno, card_type "//9-13
         " from fin_opr_register "
         " where invoice_no = '" + pub::add0(ui->leFph->text(),12) + "'";

    qDebug()<<"提取需要退费的挂号票："<<sq<<"\n";
    mdList.setQuery(sq, pub::db_o);

    if(mdList.record(0).value("name").toString().isEmpty())
    {
        QMessageBox::information(this,"注意","未找到指定票据号的挂号费！");
        return;
    }

    mdList.setHeaderData(0, Qt::Horizontal, "门诊号");
    mdList.setHeaderData(1, Qt::Horizontal, "姓名");
    mdList.setHeaderData(2, Qt::Horizontal, "诊室");
    mdList.setHeaderData(3, Qt::Horizontal, "挂号时间");
    mdList.setHeaderData(4, Qt::Horizontal, "费别");
    mdList.setHeaderData(5, Qt::Horizontal, "操作员");
    double width = ui->tvItemList->width() - 50;
    ui->tvItemList->setModel(&mdList);

    pub::setColumnWidth(ui->tvItemList, "0.15^0.15^0.2^0.25^0.125^0.125^0^0^0^0^0^0^0^0^0^0", width, 15);

    mpPerson.clear();
    mpPerson["name"] = mdList.record(0).value("name").toString();
    mpPerson["idenno"] = mdList.record(0).value("idenno").toString();   //身份证号
    mpPerson["card_type"] = mdList.record(0).value("card_type").toString();     //病志号
    mpPerson["rowid"] = mdList.record(0).value("rowid").toString();      //rowid
    mpPerson["clinic_code"] = mdList.record(0).value("clinic_code").toString();   //clinic_code
    mpPerson["pact_code"] = mdList.record(0).value("pact_code").toString();       //pack_code

    if(mdList.record(0).value("valid_flag").toString() == "0")
    {
        QMessageBox::information(this,"注意","此号已经有过作废操作！");
        ui->pbExecute->setEnabled(false);
        return;
    }

    if(mdList.record(0).value("ynsee").toString() == "1"
            && ! privFinance)
    {
        //有看诊记录，且无财务权限，不可退已经看诊记录
        QMessageBox::information(this,"注意","此号已经有过看诊记录，不能作废！");
        ui->pbExecute->setEnabled(false);
        return;
    }

    mpPerson["invoice_no"] = pub::add0(ui->leFph->text(),12);

    if(mpPerson["pact_code"] == "2")
    {
        //医保挂号
        if(!pub::useInsurance)
        {
            QMessageBox::information(this,"错误","没有进行医保登录，无法对医保号退费！");
            ui->pbExecute->setEnabled(false);
            return;
        }

        sq = "select setl_id, mdtrt_id, psn_no, insuplc_admdvs from fin_ipr_siinmaininfo "
             " where inpatient_no = '" + mpPerson["clinic_code"] + "' "
             " and invoice_no = '" + pub::add0(ui->leFph->text(),12) +"'";
        qDebug()<<"检索医保相关信息："<<sq<<"\n";
        qro->exec(sq);

        if(qro->next())
        {
            mpPerson["setl_id"] = qro->value(0).toString();
            mpPerson["mdtrt_id"] = qro->value(1).toString();
            mpPerson["psn_no"] = qro->value(2).toString();
            mpPerson["insuplc_admdvs"] = qro->value(3).toString();
        }
        else
        {
            QMessageBox::information(this,"错误","医保挂号 fin_ipr_siinmaininfo 检索失败，无法进行作废操作！");
            ui->pbExecute->setEnabled(false);
            return;
        }
    }

    ui->pbExecute->setEnabled(true);

}

void Form_tf::on_pbSearch_clicked()
{

    ui->lb_status->setText("");

    if(ui->rbG->isChecked())
    {
        //挂号票
        prepare_reg();
    }
    else
    {
        //门诊发票
        prepare_recipe();
    }

}

void Form_tf::on_pbExecute_clicked()
{
    ui->pbExecute->setEnabled(false);
    qApp->processEvents();  //刷新界面显示
    if(ui->rbG->isChecked())
    {
        if(ghtp())
        {
            QMessageBox::information(this,"注意","挂号退费操作成功！");
        }
    }
    else if(ui->rbS->isChecked())
    {
        if(fptp())
        {
            QMessageBox::information(this,"注意","发票退费操作成功！");
        }
    }
    ui->pbExecute->setEnabled(false);
    ui->pb_reprint->setEnabled(false);
    ui->lb_status->setText("退费操作结束");
}

bool Form_tf::ghtp()
{
    //挂号
    bool is_insu = false;

    if(mpPerson["pact_code"] == "2")
    {
        //医保收费
        if(!ybT())
        {
            return false;
        }

        is_insu = true;
    }

    pub::db_o.transaction();

    ui->lb_status->setText("处理医保相关数据");
    qApp->processEvents();

    if(is_insu && !saveSI())
    {
        //保存退费交易
        pub::db_o.rollback();
        return false;
    }

    ui->lb_status->setText("处理挂号相关数据");
    qApp->processEvents();

    if(!save_ret_reg())
    {
        pub::db_o.rollback();
        return false;
    }

    pub::db_o.commit();

    mdList.setQuery(NULL);

    ui->lb_status->setText("操作完成");
    qApp->processEvents();

    return true;

}

bool Form_tf::save_invo_info()
{
    ui->lb_status->setText("保存发票数据主表");
    qApp->processEvents();

    sq = "update fin_opb_invoiceinfo set CANCEL_FLAG='0'"
         " Where INVOICE_NO = '" + mpPerson["invoice_no"] + "'";
    qDebug()<<"设置 invoceinfo 作废标志："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法设置 invoiceinfo 作废标志！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    sq = "Insert into fin_opb_invoiceinfo (INVOICE_NO,TRANS_TYPE,CARD_NO,"
         "REG_DATE,NAME,PAYKIND_CODE,PACT_CODE,PACT_NAME,MCARD_NO,MEDICAL_TYPE,"
         "TOT_COST,PUB_COST,OWN_COST,PAY_COST,BACK1,BACK2,BACK3,REAL_COST,"
         "OPER_CODE,OPER_DATE,EXAMINE_FLAG,CANCEL_FLAG,CANCEL_INVOICE,"
         "CANCEL_CODE,CANCEL_DATE,CHECK_FLAG,CHECK_OPCD,BALANCE_FLAG,BALANCE_NO,"
         "BALANCE_OPCD,INVOICE_SEQ,EXT_FLAG,CLINIC_CODE,PRINT_INVOICENO,"
         "DRUG_WINDOW,ACCOUNT_FLAG,BALANCE_COMBONO)"
         " select INVOICE_NO,'2',CARD_NO,REG_DATE,NAME,PAYKIND_CODE,PACT_CODE,"
         "PACT_NAME,MCARD_NO,MEDICAL_TYPE,0-TOT_COST,0-PUB_COST,0-OWN_COST,"
         "0-PAY_COST,0-BACK1,BACK2,BACK3,0-REAL_COST,'%1',sysdate,"
         "EXAMINE_FLAG,'0',CANCEL_INVOICE,'%1',sysdate,'0','','0',BALANCE_NO,"
         "BALANCE_OPCD,INVOICE_SEQ,EXT_FLAG,CLINIC_CODE,PRINT_INVOICENO,"
         "DRUG_WINDOW,ACCOUNT_FLAG,BALANCE_COMBONO "
         " from fin_opb_invoiceinfo where invoice_no = '%2'";

    sq = sq.arg(pub::usr_code).arg(mpPerson["invoice_no"]);

    qDebug()<<"复制发票记录："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法复制发票记录！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;
}

bool Form_tf::save_invo_detail()
{
    ui->lb_status->setText("保存发票数据明细表");
    qApp->processEvents();

    sq = "update fin_opb_invoicedetail set CANCEL_FLAG='0'"
         " Where INVOICE_NO = '" + mpPerson["invoice_no"] + "'";

    qDebug()<<"设置 invocedetail 作废标志："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法设置 invoicedetail 作废标志！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    sq = "insert into fin_opb_invoicedetail (INVOICE_NO,TRANS_TYPE,INVO_SEQUENCE,"
         "INVO_CODE,INVO_NAME,PUB_COST,OWN_COST,PAY_COST,DEPT_CODE,DEPT_NAME,"
         "OPER_DATE,OPER_CODE,BALANCE_FLAG,BALANCE_NO,CANCEL_FLAG,INVOICE_SEQ)"
         " select INVOICE_NO,'2',INVO_SEQUENCE,INVO_CODE,INVO_NAME,0-PUB_COST,"
         "0-OWN_COST,0-PAY_COST,DEPT_CODE,DEPT_NAME,sysdate,'%1','0',"
         "BALANCE_NO,CANCEL_FLAG,INVOICE_SEQ"
         " from fin_opb_invoicedetail where INVOICE_NO = '%2'";
    sq = sq.arg(pub::usr_code).arg(mpPerson["invoice_no"]);

    qDebug()<<"保存 invocedetail 作废记录："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法保存 invoicedetail 作废记录！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;
}

bool Form_tf::save_fee_detail()
{
    ui->lb_status->setText("保存费用项目明细表");
    qApp->processEvents();

    sq = "update fin_opb_feedetail set CANCEL_FLAG='0'"
         " Where invoice_no = '" + mpPerson["invoice_no"] + "'";
    qDebug()<<"设置 feedetail 作废标记："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法设置 feedetail 作废标记！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    sq = "insert into fin_opb_feedetail ( RECIPE_NO,SEQUENCE_NO,TRANS_TYPE,CLINIC_CODE,"
         "CARD_NO,REG_DATE,REG_DPCD,DOCT_CODE,DOCT_DEPT,ITEM_CODE,ITEM_NAME,DRUG_FLAG,"
         "SPECS,SELF_MADE,DRUG_QUALITY,DOSE_MODEL_CODE,FEE_CODE,CLASS_CODE,UNIT_PRICE,"
         "QTY,DAYS,FREQUENCY_CODE,USAGE_CODE,USE_NAME,INJECT_NUMBER,EMC_FLAG,LAB_TYPE,"
         "CHECK_BODY,DOSE_ONCE,DOSE_UNIT,BASE_DOSE,PACK_QTY,PRICE_UNIT,PUB_COST,PAY_COST,"
         "OWN_COST,EXEC_DPCD,EXEC_DPNM,CENTER_CODE,ITEM_GRADE,MAIN_DRUG,COMB_NO,OPER_CODE,"
         "OPER_DATE,PAY_FLAG,CANCEL_FLAG,FEE_CPCD,FEE_DATE,INVOICE_NO,INVO_CODE,"
         "INVO_SEQUENCE,CONFIRM_FLAG,CONFIRM_CODE,CONFIRM_DEPT,CONFIRM_DATE,"
         "INVOICE_SEQ,NEW_ITEMRATE,OLD_ITEMRATE,EXT_FLAG,PACKAGE_CODE,PACKAGE_NAME,"
         "EXT_FLAG1,EXT_FLAG2,EXT_FLAG3,NOBACK_NUM,CONFIRM_NUM,CONFIRM_INJECT,MO_ORDER,"
         "RECIPE_SEQ,ECO_COST,over_cost,EXCESS_COST,DRUG_OWNCOST,COST_SOURCE,SUBJOB_FLAG,"
         "ACCOUNT_FLAG,UPDATE_SEQUENCENO,doctindept,MEDICALGROUPCODE,ACCOUNT_NO)"
         " select "
         " RECIPE_NO,SEQUENCE_NO,'2',CLINIC_CODE,CARD_NO,REG_DATE,REG_DPCD,DOCT_CODE,"
         "DOCT_DEPT,ITEM_CODE,ITEM_NAME,DRUG_FLAG,SPECS,SELF_MADE,DRUG_QUALITY,"
         "DOSE_MODEL_CODE,FEE_CODE,CLASS_CODE,UNIT_PRICE,0-QTY,DAYS,FREQUENCY_CODE,"
         "USAGE_CODE,USE_NAME,INJECT_NUMBER,EMC_FLAG,LAB_TYPE,CHECK_BODY,DOSE_ONCE,"
         "DOSE_UNIT,BASE_DOSE,PACK_QTY,PRICE_UNIT,0-PUB_COST,0-PAY_COST,0-OWN_COST,"
         "EXEC_DPCD,EXEC_DPNM,CENTER_CODE,ITEM_GRADE,MAIN_DRUG,COMB_NO,'%1',"
         "sysdate,PAY_FLAG,CANCEL_FLAG,'%1',sysdate,INVOICE_NO,INVO_CODE,"
         "INVO_SEQUENCE,CONFIRM_FLAG,CONFIRM_CODE,CONFIRM_DEPT,CONFIRM_DATE,"
         "INVOICE_SEQ,NEW_ITEMRATE,OLD_ITEMRATE,EXT_FLAG,PACKAGE_CODE,PACKAGE_NAME,"
         "EXT_FLAG1,EXT_FLAG2,EXT_FLAG3,NOBACK_NUM,CONFIRM_NUM,CONFIRM_INJECT,"
         "MO_ORDER,RECIPE_SEQ,ECO_COST,over_cost,EXCESS_COST,DRUG_OWNCOST,COST_SOURCE,"
         "SUBJOB_FLAG,ACCOUNT_FLAG,UPDATE_SEQUENCENO,doctindept,MEDICALGROUPCODE,"
         "ACCOUNT_NO "
         " from fin_opb_feedetail where invoice_no = '%2'";
    sq = sq.arg(pub::usr_code).arg(mpPerson["invoice_no"]);

    qDebug()<<"保存 feedetail 作废记录："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法保存 feedetail 作废记录！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;

}

bool Form_tf::save_cancel_item()
{
    ui->lb_status->setText("保存作废项目信息表");
    qApp->processEvents();

    sq = " update met_nui_cancelitem "
         " set charge_flag ='1',charge_code = '%1',"
         " charge_date = sysdate "
         " where bill_no = '%2' ";
    sq = sq.arg(pub::usr_code).arg(mpPerson["invoice_no"]);
    qDebug()<<"保存 met_nui_cancelitem 记录："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法保存 met_nui_cancelitem 记录！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;
}

bool Form_tf::save_ord_recipe()
{
    ui->lb_status->setText("保存处方表");
    qApp->processEvents();

    foreach(QString s, recipes)
    {
        sq = "update met_ord_recipedetail "
             " set status = '3' "
             " where clinic_code = '" + mpPerson["clinic_code"] + "' and recipe_no = '" + s  + "'";

        qDebug()<<"保存 met_ord_recipedetail 记录："<<sq<<"\n";
        pub::db_o.exec(sq);

        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","无法保存 met_ord_recipedetail 记录！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }

        sq = "update PHA_STO_RECIPE "
             " set recipe_state = '5' "
             " where recipe_no = '" + s  + "' and clinic_code = '" + mpPerson["clinic_code"] + "'";

        qDebug()<<"保存 pha_sto_recipe 记录："<<sq<<"\n";
        pub::db_o.exec(sq);

        if(pub::db_o.lastError().isValid())
        {
            QMessageBox::information(this,"错误","无法保存 PHA_STO_RECIPE 记录！");
            qDebug()<<pub::db_o.lastError().text()<<"\n";
            return false;
        }

    }

    return true;
}

bool Form_tf::save_ret_invoice()
{
    //保存发票退费相关信息
    if(!save_invo_info())
    {
        return false;
    }

    if(!save_invo_detail())
    {
        return false;
    }

    if(!save_fee_detail())
    {
        return false;
    }

    if(!save_cancel_item())
    {
        return false;
    }

    if(!save_ord_recipe())
    {
        return false;
    }

    return true;
}

bool Form_tf::save_ret_reg()
{
    ui->lb_status->setText("保存挂号信息");
    qApp->processEvents();

    //复制原挂号记录记录
    sq = "insert into fin_opr_register "
         "(clinic_code,trans_type,card_no,reg_date,noon_code,name,idenno,sex_code,birthday,"
         "rela_phone,address,card_type,paykind_code,paykind_name,pact_code,pact_name,"
         "mcard_no,reglevl_code,reglevl_name,dept_code,dept_name,schema_no,order_no,seeno,"
         "begin_time,end_time,doct_code,doct_name,ynregchrg,invoice_no,recipe_no,ynbook,ynfr,"
         "append_flag,reg_fee,chck_fee,diag_fee,oth_fee,own_cost,pub_cost,pay_cost,"
         "valid_flag,oper_code,oper_date,cancel_opcd,cancel_date,medical_type,icd_code,exam_code,"
         "exam_date,check_flag,check_opcd,check_date,balance_flag,balance_no,balance_opcd,"
         "balance_date,ynsee,see_date,triage_flag,triage_opcd,triage_date,print_invoicecnt,"
         "see_dpcd,see_docd,in_source,is_sendinhoscase,is_encryptname,normalname,in_date,"
         "out_date,zg,in_state,eco_cost,is_account,is_emergency,mark1,receipt_doct_code,"
         "receipt_doct_date,receipt_flag,account_no,emr_regid) "
         "select "
         "clinic_code,'2',card_no,reg_date,noon_code,name,idenno,sex_code,birthday,"
         "rela_phone,address,card_type,paykind_code,paykind_name,pact_code,pact_name,"
         "mcard_no,reglevl_code,reglevl_name,dept_code,dept_name,schema_no,order_no,seeno,"
         "begin_time,end_time,doct_code,doct_name,ynregchrg,invoice_no,recipe_no,ynbook,ynfr,"
         "append_flag,0-reg_fee,0-chck_fee,0-diag_fee,0-oth_fee,0-own_cost,0-pub_cost,0-pay_cost,"
         "'0','%1',sysdate,'%1',sysdate,medical_type,icd_code,exam_code,"
         "exam_date,check_flag,check_opcd,check_date,'0','','',"
         "balance_date,ynsee,see_date,triage_flag,triage_opcd,triage_date,print_invoicecnt,"
         "see_dpcd,see_docd,in_source,is_sendinhoscase,is_encryptname,normalname,in_date,"
         "out_date,zg,in_state,eco_cost,is_account,is_emergency,mark1,receipt_doct_code,"
         "receipt_doct_date,receipt_flag,account_no,emr_regid "
         "from fin_opr_register where rowid = '%2'";
    sq = sq.arg(pub::usr_code).arg(mpPerson["rowid"]);
    qDebug()<<"复制原挂号记录记录 : "<<sq<<"\n";

    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法保存 fin_opr_register 作废数据！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    //变更原始记录，设置作废标志
    sq = "update fin_opr_register set valid_flag = '0', cancel_opcd = '%1',"
         "cancel_date = sysdate where rowid = '%2'";
    sq = sq.arg(pub::usr_code).arg(mpPerson["rowid"]);
    qDebug()<<"变更原始记录，设置作废标志 : "<<sq<<"\n";

    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","无法设置作废标志！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;
}

bool Form_tf::saveSI()
{
    ui->lb_status->setText("保存医保相关信息");
    qApp->processEvents();

    qDebug()<<"saveSI";
    qro->exec("select max(to_number(BALANCE_NO)) from fin_ipr_siinmaininfo "
              " where inpatient_no = '" + mpPerson["clinic_code"] + "'");
    int blance_no;
    if(qro->next())
    {
        //有记录，加 1
        blance_no = qro->value(0).toInt() + 1;
    }
    else
    {
        //无记录， 赋初值 0
        blance_no = 0;
    }

    sq = "insert into fin_ipr_siinmaininfo ("
         " acct_mulaid_pay, non_insu_amount,insutype, clr_type, clr_way, "
         "hifp_pay, med_type, medfee_sumamt, preselfpay_amt, "
         " inscp_scp_amt, psn_cash_pay, fund_pay_sumamt, acct_pay, psn_type,"
         "mdtrt_cert_type,insuplc_admdvs,psn_no,mdtrt_id,ipt_otp_no,msgid,setl_id,"
         "trans_type,Inpatient_No,Balance_No,Invoice_No,Medical_Type,Patient_No,"
         "Card_No,Mcard_No,App_No,Procreate_Pcno,Si_Begindate,Si_State,Name,"
         "Sex_Code,Idenno,Spell_Code,Birthday,Empl_Type,Work_Name,Clinic_Diagnose,"
         "Dept_Code,Dept_Name,Paykind_Code,Pact_Code,Pact_Name,Bed_No,In_Date,"
         "In_Diagnosedate,In_Diagnose,In_Diagnosename,Oper_Code,Oper_Date,"
         "Reg_No,Fee_Times,Hos_Cost,Year_Cost,Out_Date,Out_Diagnose,"
         "Out_Diagnosename,Balance_Date,Tot_Cost,Pay_Cost,Pub_Cost,Item_Paycost,"
         "Base_Cost,Item_Ylcost,Item_Paycost2,Own_Cost,Over_Cost,Valid_Flag,"
         "Balance_State,Remark,Official_Cost,Type_Code,Person_Type,"
         "Primarydiagnosecode,Operatecode1,Operatecode2,Operatecode3,"
         "Primarydiagnosename,overtake_owncost,BUSINESSSEQUENCE,"
         "SERIOUSILLNESS_IN_COST,SERIOUSILLNESS_COST,SERIOUSILLNESS_TOTAL,"
         "individualbalance"
         ") select "
         " 0 - acct_mulaid_pay, 0 - non_insu_amount, insutype, clr_type, "
         "clr_way, 0 - hifp_pay, med_type, "
         " 0 - medfee_sumamt, 0 - preselfpay_amt, "
         " 0 - inscp_scp_amt, 0 - psn_cash_pay, 0 - fund_pay_sumamt, 0 - acct_pay, psn_type,"
         "mdtrt_cert_type,insuplc_admdvs,psn_no,mdtrt_id,ipt_otp_no,"
         "'%1','%2','2',Inpatient_No,'%3',Invoice_No,Medical_Type,Patient_No,"
         "Card_No,Mcard_No,App_No,Procreate_Pcno,Si_Begindate,Si_State,Name,"
         "Sex_Code,Idenno,Spell_Code,Birthday,Empl_Type,Work_Name,Clinic_Diagnose,"
         "Dept_Code,Dept_Name,Paykind_Code,Pact_Code,Pact_Name,Bed_No,In_Date,"
         "In_Diagnosedate,In_Diagnose,In_Diagnosename,'%4',sysdate,"
         "Reg_No,Fee_Times,Hos_Cost,Year_Cost,Out_Date,Out_Diagnose,"
         "Out_Diagnosename, sysdate, 0 - Tot_Cost, 0 - Pay_Cost, 0 - Pub_Cost,"
         "Item_Paycost,Base_Cost,Item_Ylcost,Item_Paycost2, "
         "0 - Own_Cost,Over_Cost,Valid_Flag,"
         "Balance_State,Remark,Official_Cost,Type_Code,Person_Type,"
         "Primarydiagnosecode,Operatecode1,Operatecode2,Operatecode3,"
         "Primarydiagnosename,overtake_owncost,BUSINESSSEQUENCE,"
         "SERIOUSILLNESS_IN_COST,SERIOUSILLNESS_COST,SERIOUSILLNESS_TOTAL,"
         "individualbalance + Pay_Cost"
         " from fin_ipr_siinmaininfo where invoice_no = '%5' and rownum = 1 ";

    sq = sq.arg(msgid2208)
            .arg(ret2208setlinfo.value("setl_id").toString())
            .arg(QString::number(blance_no))//结算序号
            .arg(pub::usr_code)//操作员
            .arg(mpPerson["invoice_no"]);//发票号
    qDebug()<<"保存医保相关退费信息："<<sq<<"\n";
    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","插入 fin_ipr_siinmaininfo 失败！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    //设置作废标记
    sq = " update fin_ipr_siinmaininfo set valid_flag = '0' "
         " where invoice_no = '" + mpPerson["invoice_no"] + "'";
    qDebug()<<"设置医保作废标记:"<<sq<<"\n";

    pub::db_o.exec(sq);

    if(pub::db_o.lastError().isValid())
    {
        QMessageBox::information(this,"错误","设置医保作废标记失败！");
        qDebug()<<pub::db_o.lastError().text()<<"\n";
        return false;
    }

    return true;
}

void Form_tf::on_leFph_returnPressed()
{
    on_pbSearch_clicked();
}

void Form_tf::on_pbExit_clicked()
{
    close();
}
bool Form_tf::fptp()
{
    //退发票
    bool is_insu = false;
    if(mpPerson["pact_code"] == "2")
    {
        //医保
        if(!ybT())
        {
            //医保退费交易失败
            return false;
        }

        is_insu = true;
    }

    pub::db_o.transaction();

    if(is_insu && !saveSI())
    {
        //保存退费交易
        //QMessageBox::information(this,"错误","保存医保数据返回异常！");
        pub::db_o.rollback();
        return false;
    }

    if(!save_ret_invoice())
    {
        pub::db_o.rollback();
        return  false;
    }

    pub::db_o.commit();
    return true;
}

void Form_tf::putBaseIn( QJsonObject &in, QString code)
{
    QString inp;
    inp = pub::getYbStrJ(code,"");   //
    if(inp.isEmpty()){
        //pub::useInsurance = false;  //设置医保不可用
        QMessageBox::information(this,"note","申请交易流水号失败！");
        return; //未能成功申请交易流水号
    }

    msgid2208 = inp;

    currentMsgid = inp;

    in.insert("infno", code);
    in.insert( "msgid", inp);
    in.insert("mdtrtarea_admvs", pub::hos_insuplc);
    in.insert("insuplc_admdvs", mpPerson["insuplc_admdvs"] );

    in.insert("insuplc_admdvs","210100");
    in.insert("recer_sys_code", "OwnSoft");
    in.insert("dev_no","");
    in.insert("dev_safe_info","");
    in.insert("cainfo", pub::hos_secretcode);
    in.insert("signtype","");
    in.insert("infver", "V1.0");
    in.insert("opter_type", "1");
    in.insert("opter", pub::usr_code);
    in.insert("opter_name", pub::usr_name);
    in.insert("inf_time", QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
    in.insert("fixmedins_code", pub::hos_ybbh);
    in.insert("fixmedins_name", pub::hos_name);
    in.insert("sign_no", pub::sign_no);

}

void Form_tf::postRequestFinished(QNetworkReply *rpl)
{
    httpFinished = true;
    qDebug()<<"http is finished in subroutin";
    QVariant statusCode = rpl->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意","http 请求状态错误: " + statusCode.toString());
        httpSuccess = false;
        return;
    }

    QNetworkReply::NetworkError err = rpl->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",rpl->errorString());
        httpSuccess = false;
        return;
    }
    else
    {
        QByteArray bt = rpl->readAll();
        QString t = QString::fromLocal8Bit(bt);

        QJsonParseError json_error;
        QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);
        if(json_error.error != 0 ){
            QMessageBox::warning(NULL,"注意","返回信息解析错误 " + json_error.errorString());
            httpSuccess = false;
            return;
        }
        qDebug()<< "2208 outDoc "<<jsdc;
        QJsonObject jsob = jsdc.object();

        if(jsob.value("infcode").toInt() != 0)
        {
            QString t = jsob.value("err_msg").toString();
            QMessageBox::warning(NULL,"注意","2208 交易失败：" + t );
            httpSuccess = false;
            return;
        }
        ret2208setlinfo = jsob.value("output").toObject().value("setlinfo").toObject();
        ret2208setldetail = jsob.value("output").toObject().value("setldetail").toObject();

        httpSuccess = true;
        qDebug()<<"httpSuccess is "<<httpSuccess;
    }
}

void Form_tf::finishedSlot(QNetworkReply *reply)
{
     if (reply->error() == QNetworkReply::NoError)
     { QString s =  reply->readAll();
         //QString str(bytes);
         //QByteArray bytes
         qDebug()<<s;

     }
     else
     {
         qDebug()<<"handle errors here";
         QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
         qDebug( "found error ....code: %d %d\n", statusCodeV.toInt(), (int)reply->error());
         qDebug()<<reply->errorString();
     }
     reply->deleteLater();
}

bool Form_tf::ybT()
{
    //医保退费交易
    ui->lb_status->setText("执行退费医保交易2208");
    qApp->processEvents();

    QJsonObject in;
    putBaseIn(  in, "2208") ;

    QJsonObject inpu,inpud;

    inpu.insert("setl_id", mpPerson["setl_id"]); //
    inpu.insert("mdtrt_id",mpPerson["mdtrt_id"]); //
    inpu.insert("psn_no", mpPerson["psn_no"]);      //

    inpud.insert("data",inpu);
    in.insert("input", inpud);

    QJsonDocument indoc ;
    indoc.setObject(in);

    //保存入参日志
    sq = "update com_business set clinic_code = '"
            + mpPerson["clinic_code"] + "',v_in = '"
            + indoc.toJson(QJsonDocument::Compact)
            + "' where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存入参日志失败！");
        qDebug()<<sq;
    }


    QNetworkReply* reply = manager.post(request,indoc.toJson());

    QEventLoop eventLoop;
    QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
    eventLoop.exec(); // 进入等待返回，但ui事件循环依然进行。

    qDebug()<<" request 2208 is returned";

    QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);

    if(!statusCode.isValid())
    {
        QMessageBox::warning(NULL,"注意","http 请求状态错误: " + statusCode.toString());
        return false;
    }

    QNetworkReply::NetworkError err = reply->error();

    if(err != QNetworkReply::NoError)
    {
        QMessageBox::warning(NULL,"注意",reply->errorString());
        return false;
    }

    QByteArray bt = reply->readAll();
    QString t = QString::fromLocal8Bit(bt);

    QJsonParseError json_error;
    QJsonDocument jsdc = QJsonDocument::fromJson(t.toUtf8(), &json_error);

    if(json_error.error != 0 )
    {
        QMessageBox::warning(NULL,"注意","返回信息解析错误 " + json_error.errorString());
        return false;
    }

    qDebug()<< "2208 outDoc "<<jsdc;
    QJsonObject jsob = jsdc.object();

    QString out_str = jsdc.toJson(QJsonDocument::Compact);
    out_str.replace("'","\\'");

    sq = "update com_business set  tmstmp = now(), v_out = '"
            + out_str
            + "' , infcode = "
            + QString::number(jsob.value("infcode").toInt())
             +   " where jyls = '" + currentMsgid + "'";

    if(!qrm->exec(sq))
    {
        QMessageBox::information(this,"错误","保存出参日志失败！");
        qDebug()<<sq;
    }

    if(jsob.value("infcode").toInt() != 0){
        QString t = jsob.value("err_msg").toString();
        QMessageBox::warning(NULL,"注意","2208 交易失败：" + t );

        return false;
    }
    ret2208setlinfo = jsob.value("output").toObject().value("setlinfo").toObject();
    ret2208setldetail = jsob.value("output").toObject().value("setldetail").toObject();

    httpSuccess = true;
    qDebug()<<"httpSuccess is "<<httpSuccess;

    if(ui->rbG->isChecked())
    {
        ui->lb_status->setText("执行挂号退号操作2202");
        qApp->processEvents();

        //挂号退费，做2202交易
        QJsonObject inpu,inpud;
        inpu.insert("ipt_otp_no", mpPerson["clinic_code"]); //住院/门诊号
        inpu.insert("mdtrt_id",mpPerson["mdtrt_id"]); //就诊ID
        inpu.insert("psn_no", mpPerson["psn_no"]);      //人员编号

        inpud.insert("data",inpu);

        QString info;
        QJsonObject retValue;

        if( ! pub::call_business("2202", inpud, info, retValue, "", true , manager, request))
        {
            QMessageBox::warning(this, "注意", info);
            //return false;
        }
    }

    return true;
}

void Form_tf::on_leFph_textChanged(const QString &arg1)
{
    Q_UNUSED(arg1)

    //发票号录入新内容，设置按钮无效
    ui->pbExecute->setEnabled(false);
    ui->pb_reprint->setEnabled(false);

}

void Form_tf::on_pb_reprint_clicked()
{
    ui->lb_status->setText("进行发票重新打印操作");
    qApp->processEvents();

    QString ret = bill_print->set_invoice_no(pub::add0(ui->leFph->text(),12));

    if(ret.isEmpty())
    {
        bill_print->print_out();
    }
    else
    {
        QMessageBox::information(this, "注意", ret);
    }

    ui->pbExecute->setEnabled(false);
    ui->pb_reprint->setEnabled(false);

    ui->lb_status->setText("发票打印操作完成");
    qApp->processEvents();

}
